using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.Threading;

using SIMA.Entities;
using SIMA.Core.Data.Collection;
using SIMA.Core.Data.Access;
using SIMA.Core.Enums;
using SIMA.Core.EventArgs;
using SIMA.Core.Security;

namespace SIMA.Services
{

	public class T_C_IncidenciaService : IT_C_IncidenciaService
	{
		#region Fields

		private SmartContainer<T_C_Incidencia> dataAccessSmart;
		private FailedEventArgs onFailed;
		private InsertedEventArgs onInserted;
		private UpdatedEventArgs onUpdated;
		private DeletedEventArgs onDeleted;
		private static Semaphore ResourceLock;
        private FilterType filter;
        private T_C_Incidencia tmpIncidencia1, tmpIncidencia2;

		#endregion

		#region Constructor

		public T_C_IncidenciaService()
		{
			DataAccess.SetConnection(SIMA.Core.Enums.AccessType.FromString, "Data Source=.;Initial Catalog=SIMA;Integrated Security=True");
			ResourceLock = new Semaphore(0, 2);
			dataAccessSmart = new SmartContainer<T_C_Incidencia>(false,true);
			dataAccessSmart.Inserted += new EventHandler<InsertedEventArgs>(dataAccessSmart_Inserted);
			dataAccessSmart.Failed += new EventHandler<FailedEventArgs>(dataAccessSmart_Failed);
			dataAccessSmart.Updated += new EventHandler<UpdatedEventArgs>(dataAccessSmart_Updated);
			dataAccessSmart.Deleted += new EventHandler<DeletedEventArgs>(dataAccessSmart_Deleted);
		}

		#endregion

		#region Implementacion de eventos del SmartContainer

        private void dataAccessSmart_Inserted(object sender, InsertedEventArgs e)
        {
            onInserted = e;
        }

        private void dataAccessSmart_Updated(object sender, UpdatedEventArgs e)
        {
            onUpdated = e;
        }

        private void dataAccessSmart_Deleted(object sender, DeletedEventArgs e)
        {
            onDeleted = e;
        }

        private void dataAccessSmart_Failed(object sender, FailedEventArgs e)
        {
            onFailed = e;
        }

		#endregion

		#region Implementando la interfaz de servicio

		public List<T_C_Incidencia> GetAllT_C_Incidencia(Profile securityProfile)
		{
			SecurityProgram.PcProfile = securityProfile;
			dataAccessSmart.SelectAll();
			return dataAccessSmart.ToList();
		}

		public IAsyncResult BeginGetAllT_C_Incidencia(Profile securityProfile, AsyncCallback callback, object state)
		{
			T_C_IncidenciaAsyncResult asyncResult = new T_C_IncidenciaAsyncResult(securityProfile, callback, state);
			ThreadPool.QueueUserWorkItem(new WaitCallback((GetAllT_C_IncidenciaCallback)), asyncResult);
			return asyncResult;
		}

		private void GetAllT_C_IncidenciaCallback(object asyncResult)
		{
			T_C_IncidenciaAsyncResult getT_C_IncidenciaAsyncResult = (T_C_IncidenciaAsyncResult)asyncResult;
			try
			{
				getT_C_IncidenciaAsyncResult.CollectionResult = GetAllT_C_Incidencia(SecurityProgram.PcProfile);
				getT_C_IncidenciaAsyncResult.ExceptionTrace = null;
				getT_C_IncidenciaAsyncResult.MessageResult = string.Empty;
			}
			catch(Exception ex)
			{
				getT_C_IncidenciaAsyncResult.CollectionResult = null;
				getT_C_IncidenciaAsyncResult.ExceptionTrace = ex;
				getT_C_IncidenciaAsyncResult.MessageResult = string.Empty;
			}
			finally
			{
				getT_C_IncidenciaAsyncResult.OnCompleted();
			}
		}

		public List<T_C_Incidencia> EndGetAllT_C_Incidencia(IAsyncResult asyncResult)
		{
			List<T_C_Incidencia> lista = null;
			using(T_C_IncidenciaAsyncResult getT_C_IncidenciaResult = asyncResult as T_C_IncidenciaAsyncResult)
			{
				getT_C_IncidenciaResult.AsyncWaitHandle.WaitOne();
				lista = getT_C_IncidenciaResult.CollectionResult;
			}
			return lista;
		}

		public List<T_C_Incidencia> GetFilteredT_C_Incidencia(Profile securityProfile, FilterType filter)
		{
            List<T_C_Incidencia> lista = null;
            this.filter = filter;
            SecurityProgram.PcProfile = securityProfile;
            switch (filter)
            {
                case FilterType.Active:
                    lista = dataAccessSmart["SelectActiveIncidencia", CommandType.StoredProcedure];
                    break;
                case FilterType.Inactive:
                    lista = dataAccessSmart["SelectInactiveIncidencia", CommandType.StoredProcedure];
                    break;
            }
            return lista;
            
		}

		public IAsyncResult BeginGetFilteredT_C_Incidencia(Profile securityProfile, FilterType filter, AsyncCallback callback, object state)
		{
            T_C_IncidenciaAsyncResult asyncResult = new T_C_IncidenciaAsyncResult(securityProfile, callback, state);
            ThreadPool.QueueUserWorkItem(new WaitCallback((GetFilteredT_C_IncidenciaCallback)), asyncResult);
            return asyncResult;
		}

        private void GetFilteredT_C_IncidenciaCallback(object asyncResult)
        {
            T_C_IncidenciaAsyncResult getT_C_IncidenciaAsyncResult = (T_C_IncidenciaAsyncResult)asyncResult;
            try
            {
                getT_C_IncidenciaAsyncResult.CollectionResult = GetFilteredT_C_Incidencia(SecurityProgram.PcProfile, this.filter);
                getT_C_IncidenciaAsyncResult.ExceptionTrace = null;
                getT_C_IncidenciaAsyncResult.MessageResult = string.Empty;
            }
            catch (Exception ex)
            {
                getT_C_IncidenciaAsyncResult.CollectionResult = null;
                getT_C_IncidenciaAsyncResult.ExceptionTrace = ex;
                getT_C_IncidenciaAsyncResult.MessageResult = string.Empty;
            }
            finally
            {
                getT_C_IncidenciaAsyncResult.OnCompleted();
            }
        }

		public List<T_C_Incidencia> EndGetFilteredT_C_Incidencia(IAsyncResult asyncResult)
		{
            List<T_C_Incidencia> lista = null;
            using (T_C_IncidenciaAsyncResult getT_C_IncidenciaResult = asyncResult as T_C_IncidenciaAsyncResult)
            {
                getT_C_IncidenciaResult.AsyncWaitHandle.WaitOne();
                lista = getT_C_IncidenciaResult.CollectionResult;
            }
            return lista;
		}

		public string RegisterT_C_Incidencia(Profile securityProfile, T_C_Incidencia newItem)
		{
            SecurityProgram.PcProfile = securityProfile;
            tmpIncidencia1 = newItem;
            dataAccessSmart.Add(newItem);
            ResourceLock.WaitOne(1000);
            return "Nuevo registro de Incidencia creado.";
		}

		public IAsyncResult BeginRegisterT_C_Incidencia(Profile securityProfile, T_C_Incidencia newItem, AsyncCallback callback, object state)
		{
            T_C_IncidenciaAsyncResult asyncResult = new T_C_IncidenciaAsyncResult(securityProfile, callback, state);
            ThreadPool.QueueUserWorkItem(new WaitCallback((RegisterT_C_IncidenciaCallback)), asyncResult);
            return asyncResult;
		}

        private void RegisterT_C_IncidenciaCallback(object asyncResult)
        {
            T_C_IncidenciaAsyncResult t_c_IncidenciaAsyncResult = (T_C_IncidenciaAsyncResult)asyncResult;
            try
            {
                t_c_IncidenciaAsyncResult.CollectionResult = null;
                t_c_IncidenciaAsyncResult.ExceptionTrace = null;
                t_c_IncidenciaAsyncResult.MessageResult = RegisterT_C_Incidencia(SecurityProgram.PcProfile, tmpIncidencia1);

            }
            catch (Exception ex)
            {
                t_c_IncidenciaAsyncResult.CollectionResult = null;
                t_c_IncidenciaAsyncResult.ExceptionTrace = ex;
                t_c_IncidenciaAsyncResult.MessageResult = string.Empty;
            }
            finally
            {
                t_c_IncidenciaAsyncResult.OnCompleted();
                tmpIncidencia1 = null;
            }

        }

		public string EndRegisterT_C_Incidencia(IAsyncResult asyncResult)
		{
            string msg = string.Empty;
            using (T_C_IncidenciaAsyncResult t_c_IncidenciaAsyncResult = asyncResult as T_C_IncidenciaAsyncResult)
            {
                asyncResult.AsyncWaitHandle.WaitOne();
                msg = t_c_IncidenciaAsyncResult.MessageResult;
            }
            return msg;
		}

		public string UpdateT_C_Incidencia(Profile securityProfile, T_C_Incidencia itemToUpdate, T_C_Incidencia itemUpdated)
		{
            SecurityProgram.PcProfile = securityProfile;
            tmpIncidencia1 = itemToUpdate;
            tmpIncidencia2 = itemUpdated;
            dataAccessSmart.Update(tmpIncidencia1, tmpIncidencia2);
            ResourceLock.WaitOne(1000);
            return "Cambio de Incidencia realizado.";
		}

		public IAsyncResult BeginUpdateT_C_Incidencia(Profile securityProfile, T_C_Incidencia itemToUpdate, T_C_Incidencia itemUpdated, AsyncCallback callback, object state)
		{
            T_C_IncidenciaAsyncResult asyncResult = new T_C_IncidenciaAsyncResult(securityProfile, callback, state);
            ThreadPool.QueueUserWorkItem(new WaitCallback((UpdateT_C_IncidenciaCallback)), asyncResult);
            return asyncResult;
		}

        private void UpdateT_C_IncidenciaCallback(object asyncResult)
        {
            T_C_IncidenciaAsyncResult t_c_IncidenciaAsyncResult = (T_C_IncidenciaAsyncResult)asyncResult;
            try
            {
                t_c_IncidenciaAsyncResult.CollectionResult = null;
                t_c_IncidenciaAsyncResult.ExceptionTrace = null;
                t_c_IncidenciaAsyncResult.MessageResult = UpdateT_C_Incidencia(SecurityProgram.PcProfile, tmpIncidencia1, tmpIncidencia2);

            }
            catch (Exception ex)
            {
                t_c_IncidenciaAsyncResult.CollectionResult = null;
                t_c_IncidenciaAsyncResult.ExceptionTrace = ex;
                t_c_IncidenciaAsyncResult.MessageResult = string.Empty;
            }
            finally
            {
                t_c_IncidenciaAsyncResult.OnCompleted();
                tmpIncidencia1 = null;
                tmpIncidencia2 = null;
            }
        }

		public string EndUpdateT_C_Incidencia(IAsyncResult asyncResult)
		{
            string msg = string.Empty;
            using (T_C_IncidenciaAsyncResult t_c_IncidenciaAsyncResult = asyncResult as T_C_IncidenciaAsyncResult)
            {
                asyncResult.AsyncWaitHandle.WaitOne();
                msg = t_c_IncidenciaAsyncResult.MessageResult;
            }
            return msg;
		}

		public string DeleteT_C_Incidencia(Profile securityProfile, T_C_Incidencia dropItem)
		{
            SecurityProgram.PcProfile = securityProfile;
            tmpIncidencia1 = dropItem;
            dataAccessSmart.Remove(dropItem);
            ResourceLock.WaitOne(1000);
            return "Baja de Incidencia realizada.";
		}

		public IAsyncResult BeginDeleteT_C_Incidencia(Profile securityProfile, T_C_Incidencia dropItem, AsyncCallback callback, object state)
		{
            T_C_IncidenciaAsyncResult asyncResult = new T_C_IncidenciaAsyncResult(securityProfile, callback, state);
            ThreadPool.QueueUserWorkItem(new WaitCallback((DeleteT_C_IncidenciaCallback)), asyncResult);
            return asyncResult;
		}

        private void DeleteT_C_IncidenciaCallback(object asyncResult)
        {
            T_C_IncidenciaAsyncResult t_c_IncidenciaAsyncResult = (T_C_IncidenciaAsyncResult)asyncResult;
            try
            {
                t_c_IncidenciaAsyncResult.CollectionResult = null;
                t_c_IncidenciaAsyncResult.ExceptionTrace = null;
                t_c_IncidenciaAsyncResult.MessageResult = DeleteT_C_Incidencia(SecurityProgram.PcProfile, tmpIncidencia1);

            }
            catch (Exception ex)
            {
                t_c_IncidenciaAsyncResult.CollectionResult = null;
                t_c_IncidenciaAsyncResult.ExceptionTrace = ex;
                t_c_IncidenciaAsyncResult.MessageResult = string.Empty;
            }
            finally
            {
                t_c_IncidenciaAsyncResult.OnCompleted();
                tmpIncidencia1 = null;
            }
        }

		public string EndDeleteT_C_Incidencia(IAsyncResult asyncResult)
		{
         string msg = string.Empty;
            using (T_C_IncidenciaAsyncResult t_c_IncidenciaAsyncResult = asyncResult as T_C_IncidenciaAsyncResult)
            {
                asyncResult.AsyncWaitHandle.WaitOne();
                msg = t_c_IncidenciaAsyncResult.MessageResult;
            }
            return msg;
        
		}


		#endregion
	}
}
